package icasue.net.socket.driver.event;

import com.alibaba.fastjson.JSON;
import icasue.net.base.annotations.NotNull;
import icasue.net.base.annotations.Nullable;
import icasue.net.protocol.carfun.common.CommandResponse;
import icasue.net.socket.dto.event.channel.ChannelJoinMes;
import icasue.net.socket.dto.event.channel.ChannelQuitMes;
import icasue.net.socket.exception.ClientConnectException;
import icasue.net.socket.exception.CommandExecException;
import icasue.net.socket.exception.ProtocolUnSupportException;
import icasue.net.socket.model.register.RegisterInfo;
import icasue.net.socket.share.MindManger;
import icasue.net.socket.thread.Channel;
import icasue.net.socket.thread.SocketProxy;
import icasue.net.socket.utils.Assert;
import icasue.net.protocol.carfun.commands.EventCommand;

/**
 * @Author: Qiao Hang
 * @CreateDate: 2021/3/23 上午10:04
 * @UpdateDate:
 * @Description:
 */
public class ChannelEventCommandDriver implements EventCommandDriver<EventCommand.EventChannel, RegisterInfo> {

    @Override
    public EventCommand.EventChannel[] getSupportCommands() {
        return EventCommand.EventChannel.values();
    }

    @Override
    @Nullable
    public CommandResponse<JSON> dealEventCommand(@NotNull EventCommand.EventChannel command,
                                                  @NotNull SocketProxy<RegisterInfo> proxy,
                                                  @NotNull RegisterInfo registerInfo,
                                                  @NotNull Object channelId,
                                                  @Nullable JSON data) throws ProtocolUnSupportException, CommandExecException, ClientConnectException {
        //command,socketProxy, registerInfo,channelId must not be null.
        Assert.notNullAll(command,proxy,registerInfo,channelId);
        //touch channel, if channel has benn release(all client had UN_BIND) will ignore this mes.
        Channel channel = MindManger.channels.get(channelId);
        if(channel == null){ return null; }
        //protocol result.
        CommandResponse<JSON> result = null;
        switch (command){
            case EVENT_CHANNEL_JOIN:
                result = pushMesChannelJoin(command,proxy,channel,registerInfo,data);
                break;
            case EVENT_CHANNEL_QUIT:
                result = pushMesChannelQuit(command,proxy,channel,registerInfo,data);
                break;
            default:
                /*抛出EventCommandUnSupport异常，
                实际Command经过parse,chooseDriver,sendEvent三个阶段，
                是确认没有问题的，也是服务端支持的EventCommand*/
                throw new ProtocolUnSupportException("Protocol ["+command.getCommand()+"] UnSupport.");
        }
        return result;
    }


    /**
     * 业务事件 channel_join 推送客户端
     * @param command
     * @param proxy
     * @param registerInfo
     * @param channel
     * @param data
     * @return
     */
    @Nullable
    private CommandResponse<JSON> pushMesChannelJoin(@NotNull EventCommand.EventChannel command,
                                                     @NotNull SocketProxy<RegisterInfo> proxy,
                                                     @NotNull Channel channel,
                                                     @NotNull RegisterInfo registerInfo,
                                                     @Nullable JSON data) {
        //构建响应数据
        ChannelJoinMes channelJoinMes = new ChannelJoinMes(registerInfo.getIdentity(),registerInfo);
        return CommandResponse.success(channelJoinMes);
    }


    /**
     * 业务事件 channel_quit 推送客户端
     * @param command
     * @param proxy
     * @param registerInfo
     * @param channel
     * @param data
     * @return
     */
    @Nullable
    private CommandResponse<JSON> pushMesChannelQuit(@NotNull EventCommand.EventChannel command,
                                                     @NotNull SocketProxy<RegisterInfo> proxy,
                                                     @NotNull Channel channel,
                                                     @NotNull RegisterInfo registerInfo,
                                                     @Nullable JSON data) {
        //构建响应数据
        ChannelQuitMes channelQuitMes = new ChannelQuitMes(registerInfo.getIdentity(),registerInfo);
        return CommandResponse.success(channelQuitMes);
    }


}
